package com.google.code.jaail.networks;

import com.google.code.jaail.networks.connection.ConnectionStatus;
import com.google.code.jaail.networks.protocols.ChatProtocol;
import com.google.code.jaail.user.MessageReceiver;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ChatNetwork {

    private final String name;
    public int portSetting;
    public final ChatProtocol chatProtocol;
    public final Socket socket;
    private final List<MessageReceiver> messageReceivers;
    private OutputStream os;
    private InputStream is;
    private InetSocketAddress inetSocketAddress;
    private final InetSocketAddressHelper inetSocketAddressHelper;

    public ChatNetwork(String name, String networkAddress, ChatProtocol chatProtocol) throws UnknownHostException {
        this.name = name;
        this.chatProtocol = chatProtocol;
        messageReceivers = Collections.synchronizedList(new ArrayList<MessageReceiver>());
        socket = new Socket();
        inetSocketAddressHelper = new InetSocketAddressHelper(networkAddress);
    }

    public ChatNetwork(String name, InetSocketAddressHelper helper, Socket socket, ChatProtocol chatProtocol) throws UnknownHostException {
        this.name = name;
        inetSocketAddressHelper = helper;
        this.socket = socket;
        this.chatProtocol = chatProtocol;
        messageReceivers = Collections.synchronizedList(new ArrayList<MessageReceiver>());
    }

    public void connect() throws UnknownHostException, IOException {
        inetSocketAddress = inetSocketAddressHelper.lookupInetSocketAddress(portSetting);
        socket.connect(inetSocketAddress);
        os = socket.getOutputStream();
        is = socket.getInputStream();
        //Todo: do protocol stuff to negotiate connections
        chatProtocol.negotiateConnection(os, is);
        //Todo: start a new thread to prevent blocking?
    }

    public void disconnect() throws IOException {
        chatProtocol.negotiateDisconnect(os, is);
        if(socket.isConnected()){
            os.close();
            is.close();
            socket.close();
        }
    }

    public ConnectionStatus connectionStatus() {
        return chatProtocol.connectionStatus();
    }

    public void addMessageReceiver(MessageReceiver messageReceiver) {
        this.messageReceivers.add(messageReceiver);

    }

    public int getPortSetting() {
        return portSetting;
    }

    public void setPortSetting(int portSetting) {
        this.portSetting = portSetting;
    }

    public InetSocketAddress getInetSocketAddress() {
        return inetSocketAddress;
    }
}
